import chisel3._
import chisel3.util._  
import config.Configs._

class tlbtran_to_csr_bundle extends Bundle{
  //from_ls
  val tlbsrch_hit=Bool()
  val tlbsrch_wen=Bool()
  val tlbrd_en=Bool()
  val tlbidx =new csr_tlbidx_bundle()
  val tlbehi =new csr_tlbehi_bundle()
  val tlbelo0=new csr_tlbelo_bundle()
  val tlbelo1=new csr_tlbelo_bundle()
  val asid   =new csr_asid_bundle()
}
class tlbtran_to_tlb_bundle extends Bundle{
  val rand_idx=UInt(log2Ceil(TLB_NUM).W)
  val ecode3f=Bool()

  val tlbidx =new csr_tlbidx_bundle()
  val tlbehi =new csr_tlbehi_bundle()
  val tlbelo0=new csr_tlbelo_bundle()
  val tlbelo1=new csr_tlbelo_bundle()
  val asid   =new csr_asid_bundle()

}
class tlbtran_io_bundle extends Bundle{
  val to_csr=Input(new tlbtran_to_csr_bundle())
  val to_tlb=Output(new tlbtran_to_tlb_bundle())
}
class mmutran_to_tlb_bundle extends Bundle{
  val da  =Bool()
  val pg  =Bool()
  val plv =UInt(2.W)
  val dmw0=new csr_dmw_bundle()
  val dmw1=new csr_dmw_bundle()
  val datf   =UInt(2.W)
  val datm   =UInt(2.W)
}

class mmutran_io_bundle extends Bundle{
  val to_mmu=Output(new mmutran_to_tlb_bundle())
}

class inst_tlb_excp_bundle extends Bundle{
  val tlbr=Bool()
  val pif =Bool()
  val ppi =Bool()
}

class data_tlb_excp_bundle extends Bundle{
  val tlbr=Bool()
  val pme =Bool()
  val ppi =Bool()
  val pix =Bool()
}

// 指令虚拟地址到物理地址转换的数据Bundle
class inst_vaddr_to_paddr_bundle extends Bundle{
  val addr_en = Input(Bool())              // 地址转换使能信号
  val vaddr   = Input(UInt(ADDR_WIDTH.W))  // 输入：虚拟地址
  val paddr   = Output(UInt(ADDR_WIDTH.W)) // 输出：物理地址
  val excp    = Output(new inst_tlb_excp_bundle()) // 输出：TLB异常信息（指令相关）
  val direct_uncache = Output(Bool())      // 输出：是否直连非缓存区（直接uncache）
  val page_uncache   = Output(Bool())      // 输出：是否页表非缓存区（页面uncache）
}


// 数据虚拟地址到物理地址转换的数据Bundle
class data_vaddr_to_paddr_bundle extends Bundle{
  val addr_en = Input(Bool())              // 地址转换使能信号
  val vaddr   = Input(UInt(ADDR_WIDTH.W))  // 输入：虚拟地址
  val paddr   = Output(UInt(ADDR_WIDTH.W)) // 输出：物理地址
  val excp    = Output(new data_tlb_excp_bundle()) // 输出：TLB异常信息（数据相关）
  val uncache = Output(Bool())             // 输出：是否非缓存区
}

// TLB查找时使用的Bundle（单路）
class tlb_s_bundle extends Bundle{
  val fetch  = Input(Bool())               // 是否取指令（Fetch阶段）
  val vppn   = Input(UInt(19.W))           // 虚拟页号（Virtual Page Number，19位）
  val va_12  = Input(UInt(1.W))            // 虚拟地址低位（bit12），用于4KB页等
  val asid   = Input(UInt(10.W))           // 地址空间标识（Address Space ID，10位）

  val hit    = Output(Bool())              // 输出：是否命中TLB
  val index  = Output(UInt(log2Ceil(TLB_NUM).W)) // 输出：命中TLB的索引
  val ps4kb  = Output(UInt(6.W))           // 输出：页面大小（以4KB为单位，6位）
  val ppn    = Output(UInt(20.W))          // 输出：物理页号（Physical Page Number）
  val v      = Output(UInt(1.W))           // 输出：该条目是否有效（Valid位）
  val d      = Output(UInt(1.W))           // 输出：该条目是否可写（Dirty/可写位）
  val mat    = Output(UInt(2.W))           // 输出：内存属性类型（Memory Attribute Type）
  val plv    = Output(UInt(2.W))           // 输出：特权等级（Privilege Level）
}


// TLB写入和读取时使用的Bundle（包含完整TLB条目信息）
class tlb_w_and_r_bundle extends Bundle{
  val vppn  = UInt(19.W)   // 虚拟页号
  val asid  = UInt(10.W)   // 地址空间标识
  val g     = UInt(1.W)    // 全局位（Global），为1时忽略ASID比较
  val ps    = UInt(6.W)    // 页面大小（Page Size），6位
  val e     = UInt(1.W)    // 有效位（Entry Valid）

  // 第一子页表（0）相关信息
  val v0    = UInt(1.W)    // 有效位
  val d0    = UInt(1.W)    // Dirty位/写使能
  val mat0  = UInt(2.W)    // 内存属性类型
  val plv0  = UInt(2.W)    // 特权等级
  val ppn0  = UInt(20.W)   // 物理页号

  // 第二子页表（1）相关信息
  val v1    = UInt(1.W)    // 有效位
  val d1    = UInt(1.W)    // Dirty位/写使能
  val mat1  = UInt(2.W)    // 内存属性类型
  val plv1  = UInt(2.W)    // 特权等级
  val ppn1  = UInt(20.W)   // 物理页号
}

class ls_to_mmuctrl_bundle extends Bundle{
  val tlbrd_en   =Bool()
  val tlbwr_en   =Bool()
  val tlbsrch_wen=Bool()
  val tlbfill_en =Bool()

  val invtlb_en  =Bool()
  val invtlb_op  =UInt(5.W)
  val invtlb_asid=UInt(10.W)
  val invtlb_va  =UInt(ADDR_WIDTH.W)
}

class ex_to_mmuctrl_bundle extends Bundle{
  val tlbsrch_en=Bool()
  val is_tlbsrch=Bool()
}

class mmu_with_tlb_inv_bundle extends Bundle{
  val en=Bool()
  val op=UInt(5.W)
  val asid=UInt(10.W)
  val va=UInt(19.W)
}